package com.jomoo.css.common.core.context;

import com.alibaba.ttl.TransmittableThreadLocal;
import com.jomoo.css.common.core.bean.util.SpringUtil;
import com.jomoo.css.common.core.vo.SysUserVO;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * bo.wang
 * 2017-11-23
 */
public class ContextHolder implements ApplicationContextAware {
    /**
     * 保存HttpServletResponse的线程局部变量.
     */
    private static final ThreadLocal<HttpServletResponse> responseThreadLocal = new ThreadLocal<HttpServletResponse>();
    /**
     * 保存HttpServletRequest的线程局部变量.
     */
    private static final ThreadLocal<HttpServletRequest> requestThreadLocal = new ThreadLocal<HttpServletRequest>();

    private static final ThreadLocal<HttpSession> httpSessionThreadLocal = new ThreadLocal<HttpSession>();

    //保存用于跨服务器和二级域共享的sid
    private static final ThreadLocal<String> sidThreadLocal = new ThreadLocal<String>();
    //保存用于跨服务器和二级域共享的sid
    private static final ThreadLocal<String> remoteIpThreadLocal = new ThreadLocal<String>();

    private static final ThreadLocal<String> THREAD_LOCAL_TENANT = new TransmittableThreadLocal<>();

    private static final ThreadLocal<SysUserVO> THREAD_LOCAL_USER = new TransmittableThreadLocal<>();

    private static ApplicationContext applicationContext;

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public void setApplicationContext(ApplicationContext context) {
        Assert.notNull(context, "WebApplicationContext can not be null");
        applicationContext = context;
    }

    @SuppressWarnings("unchecked")
    public static <T> T getBean(String beanId) {
        return (T) applicationContext.getBean(beanId);
    }

    public static HttpServletRequest getRequest() {
        return requestThreadLocal.get();
    }

    public static HttpServletResponse getResponse() {
        return responseThreadLocal.get();
    }

    public static HttpSession getHttpSession() {
        return httpSessionThreadLocal.get();
    }

    public static String getSid() {
        return sidThreadLocal.get();
    }

    public static void setRemoteIp(String sid) {
        remoteIpThreadLocal.set(sid);
    }

    public static String getRemoteIp() {
        return remoteIpThreadLocal.get();
    }

    public static void setSid(String sid) {
        sidThreadLocal.set(sid);
    }


    /**
     * TTL 设置租户ID
     *
     * @param tenantId
     */
    public static void setTenantId(String tenantId) {
        THREAD_LOCAL_TENANT.set(tenantId);
    }

    /**
     * 获取TTL中的租户ID
     *
     * @return
     */
    public static String getTenantId() {
         String tenantId=THREAD_LOCAL_TENANT.get();
         return tenantId;
    }

    public static void setHttpRequestResponseHolder(HttpServletRequest request, HttpServletResponse response) {
        responseThreadLocal.set(response);
        requestThreadLocal.set(request);
        httpSessionThreadLocal.set(request.getSession());
    }

    public static void clean() {
        responseThreadLocal.remove();
        requestThreadLocal.remove();
        httpSessionThreadLocal.remove();
        sidThreadLocal.remove();
        THREAD_LOCAL_TENANT.remove();
    }

    public static SysUserVO getCurrentUser() {
        IContextHolder contextHolder = SpringUtil.getBean(IContextHolder.class);
        if (contextHolder != null) {
            return contextHolder.getCurrentUser();
        } else {
            throw new UnsupportedOperationException("需要在项目中实现IContextHolder接口并注入到spring context");
        }
    }
}
